<!--
 *@description:
 *@author: Ming
 *@date: 2021-05-22 15:33:22
 *@version: V1.0.5
-->
<template>
  <div class="popover" ref="popover">
      <transition name="lm-popover">
        <div :class="['contenWrapper',`position-${position}`]" ref="contenWrapper" v-show="visible">
          <slot name="content" :close="close"></slot>
        </div>
      </transition>
      <span ref="triggerWrapper" class="trigger">
        <slot></slot>
      </span>
  </div>
</template>

<script>
export default {
  name:"LmPopover",
  data() {
    return {
      visible:false,
    };
  },
  props: {
    position:{
      type:String,
      default:'top',
      validator(value){
        return ['top','bottom','left','right'].indexOf(value)>=0
      }
    },
    trigger:{
      type:String,
      default:'click',
      validator(value){
        return ['click','hover'].indexOf(value)>=0
      }
    }
  },
  computed: {
    openEvent(){
      if(this.trigger === 'click'){
        return 'click'
      }else{
        return 'mouseenter'
      }
    },
    closeEvent(){
      if(this.trigger === 'click'){
        return 'click'
      }else{
        return 'mouseleave'
      }
    }
  },
  mounted(){
    const { popover } = this.$refs
    if(this.trigger === 'click'){
      popover.addEventListener('click',this.onClick)
    }else{
      popover.addEventListener('mouseenter',this.open)
      popover.addEventListener('mouseleave',this.close)
    }
  },
  destroyed () {
    const { popover } = this.$refs
    if(this.trigger === 'click'){
      popover.removeEventListener('click',this.onClick)
    }else{
      popover.removeEventListener('mouseenter',this.open)
      popover.removeEventListener('mouseleave',this.close)
    }
  },
  methods: {
    // 创建 定位当前tips
    positionContent(){
      document.body.appendChild(this.$refs.contenWrapper)
      const {contenWrapper,triggerWrapper} =this.$refs
      let {width, height, top, left} = triggerWrapper.getBoundingClientRect()
      let {height:contenHeight} = contenWrapper.getBoundingClientRect()
      const positions ={
        'top':{
          top:top + window.scrollY,
          left:left + window.scrollX
        },
        'bottom':{
          top:top + window.scrollY + height,
          left:left + window.scrollX
        },
        'left':{
          top:top + window.scrollY +(height-contenHeight)/2,
          left:left + window.scrollX
        },
        'right':{
          top:top + window.scrollY +(height-contenHeight)/2,
          left:left + window.scrollX + width
        }
      }
      contenWrapper.style.top = `${positions[this.position].top}px`
      contenWrapper.style.left = `${positions[this.position].left}px`
    },
    onClickDoncument(e){
      // 如果 当前点击的是popover 元素 或者属于popover的子元素则不关闭直接return
      if (
          this.$refs.popover 
          && (this.$refs.contenWrapper === e.target || this.$refs.popover.contains(e.target))
        ) return
        this.close()
    },
    open (){
      this.visible = true
      this.$nextTick(()=>{
        this.positionContent()
        document.addEventListener('click',this.onClickDoncument)
      })
    },
    close(){
      this.visible = false
      document.removeEventListener('click',this.onClickDoncument)
    },
    onClick(){
      if(this.visible === true){
        this.close()
      }else{
        this.open()
      }
    }
  },
};
</script>

<style lang="scss" scoped>
$border-color:#ebeef5;
$border-radius:4px;
.popover{
    display: inline-block;
    vertical-align: top;
    position: relative;
    
    .trigger{
      display: inline-block;
    }
}
.contenWrapper{
  position: absolute;
  border: 1px solid $border-color;
  background: #fff;
  min-width: 150px;
  border-radius: $border-radius;
  filter: drop-shadow(0 0 3px rgba(0,0,0,0.1));
  color: #606266;
  line-height: 1.4;
  text-align: justify;
  font-size: 14px;
  word-break: break-all;
  padding: 18px 20px;
  max-width: 20em;
  &.lm-popover-enter-active, &.lm-popover-leave-active {
    transition: all .3s;
  }
  &.lm-popover-enter, &.lm-popover-leave-to /* .fade-leave-active below version 2.1.8 */ {
    opacity: 0;
  }
  &.position-top{
    transform: translateY(-100%);
    margin-top: -5px;
    &::after{
      bottom: -5px;
      margin-left: 10px;
      border-bottom-width: 0;
      border-top-color: #fff;
    }
  }
  &.position-bottom{
    margin-top: 5px;
    &::after{
      top: -5px;
      margin-left: 10px;
      border-top-width: 0;
      border-bottom-color: #fff;
    }
  }
  &.position-left{
    margin-left: -10px;
    transform: translateX(-100%);
    &::after{
      right: -5px;
      top:50%;
      transform: translatey(-50%);
      margin-left: 10px;
      border-right-width: 0;
      border-left-color: #fff;
    }
  }
  &.position-right{
    margin-left: 5px;
    &::after{
      left: -5px;
      margin-right: 10px;
      top: 50%;
      transform: translatey(-50%);
      border-left-width: 0;
      border-right-color: #fff;
    }
  }
  &::after{
    content: " ";
    border-width: 6px;
    position: absolute;
    display: block;
    width: 0;
    height: 0;
    border-color: transparent;
    border-style: solid;
  }
}
</style>